Skip to content

Conversation

ilsea
Copy link
Member

@ilsea ilsea commented Oct 8, 2026

Add BookDetailPage (rating, notes, shelf)

Closes #5, Closes #23, Closes #29

Adds the book details page at /book/:id, following the mockup, plus the shared components it needed. It runs on mock data until the backend is ready.

What's new

  • BookDetailPage: cover with shelf ribbon, title, authors, genres, description and facts, and the user's own rating and notes.
  • MyNotesPanel: clickable star rating (with hover preview and "Clear rating"), and a note that can be added, edited and deleted.
  • ConfirmDialog: asks before removing a book that has a rating or note, and before deleting a note.
  • ShelfRibbon: moved out of BookCard so the detail page can reuse it.
  • Eyebrow: sparkle icon + small label, used for the shelf status. Reusable for other pages.
  • Button: new text variant. Existing variants are unchanged.

Changes to existing files (for reviewers)

  • Url → URL in variable names (BookCover, BookCard).
  • All exports are now named instead of default (App, AppShell, with imports updated).
  • Prop types renamed to ComponentNameProps (BookCover, SearchField, icons). SearchIcon.tsx file name fixed.
  • "plank" added to the names for the decorative shelf element (BookCard, BookGrid, tokens.css). Decor element and page were at some point both called "shelf" (confusing).
  • SearchField now uses --color-header-tint instead of --color-chip-bg, so chips can be recolored without side effects.
  • Hardcoded values in ShelfRibbon and Button replaced with tokens.
  • Favicon added.
  • The last commit runs Prettier on /client, so formatting changes show up in many files.

Temporary (needs the backend)

  • mockBooks.ts and a temporary shelf entry type stand in for the real query. Marked TEMPORARY in the code.
  • "Book not found" needs real loading and error states.
  • updatedAt is set by the client and should be set by the server.
  • Note max length (1000) must also be validated by the server.
  • Removing a book from the shelf should be one backend operation that also deletes the rating and note (cascade).
  • Language shows "en", so it needs a converter or real data.
  • Shelf changes are only kept while on the page, not between pages.

Not included yet

Back link, prev/next, loading and error states, and an accessibility pass (keyboard support for the stars and focus ring on the ribbon over dark covers).

How to test

Open /book/<id> with an id from the mock data (currently available: mock-001, mock-002, mock-003).
Example: http://localhost:5173/book/mock-003

Rate a book, add, edit and delete a note, and toggle the ribbon. Removing a book that has a rating or note should show the confirm popup.

AI use

Claude was used to provide skeleton code for the structure, the CSS and parts of the component code, as well as consulting on how to change the solutions along the way. Design decisions, component behavior/rules and testing were done by me.

ilsea added 20 commits October 8, 2026 08:58
Add bookishFavicon.svg in public folder. Change favicon path in index.html.

Clean up unnecessary comments and formatting in a couple icon files. No change to funcitonality.
files
- BookCover.tsx
- BookCard.tsx

This should not affect any other current files, but clears up possible confusion and prevents case errors.
To ensure naming consistency across project. Also update files where these are imported, so they are referenced correctly.

Functions changed:
- App.tsx
- AppShell.tsx

Imports updated:
- App.tsx
- main.tsx
Change all occurences of "Prop" to "ComponentNameProp".  Should not affect any other files - all instances are internal to each file.

Affected files:
- BookCover.tsx
- SearchField.tsx
- BrowseIcon.tsx
- ChevronIcon.tsx
- FilterIcon.tsx
- LogoIcon.tsx
- RibbonIcon.tsx
- SearchIcon.tsx
- ShelfIcon.tsx
- SparkeIcon.tsx
- StarIcon.tsx
FIle: SearchIcon.tsx
Also update imports used in other files to reflect this: SearchField.tsx
To avoid confusing these with the "My shelf" page.

Affected files:
- BookCard.module.css
- BookCard.tsx
- BookGrid.module.css
- BookGrid.tsx
- tokens.css
Previously living inside BookCard.tsx, now it's own file. Change relevant sections in related files.

Why: To allow reuse of ribbon button by other parts of the app (mainly Book Detail Page).

New files:
- ShelfRibbon.tsx
- ShelfRibbon.module.css

Modified files:
- BookCard.tsx
- BookCard.module.css
`--color-chip-bg` changed to more correct `color-header-tint` in SearchField.module.css

Allows recoloring of actual color chip bg without inadvertently changing other elements.
- Button.tsx
- Button.module.css

Add a text-only button for various uses across the app (such as "remove rating" on detail page). Default values for button are the same as before, it should not impact any other current files.

At the same time clean up hardcoded .css values, replace with var() from tokens.css
What a weird name for this thing...
- Eyebrow.tsx
- Eyebrow.module.css
For use in book detail page.

Why and when it triggers:

Removing book from your shelf also deletes your rating and notes

Deleting notes cannot be undone

The popup is handled by the app itself, overwriting some of the automatic behavior in the browser.
Includes:
- Current rating, interactive, can be changed by just clicking the stars.
- Button to remove rating
- Note status / existing note
- Text box to write note when creating new/editing
- Buttons to create note, save or discard drafted note, delete existing note.

Note: You cannot save a note with zero text. If you want to remove a note, you need to cancel any current edit/draft, and instead click "delete note"
Uses newly created components. Based on visual mockup from planning phase.

TEMPORARY:
- Uses mockBooks.ts instead of real query to backend. This includes mapping of mock books currently in .json file in /server, plus a temp shelf entry type.
- "Book not found" only works with static list of books - must be replaced with dynamic error/loading state management when linked with real backend.
- Sets updatedAt date itself for user notes. this should be done by the server
- Language currently shows "en", not full language. Have to see how this behaves with actual date, perhaps add a converter util to do "en" -> "English"
- Max length of user note is handled by MyNotesPanel.tsx, needs to be validated by server as well
- Remove book from shelf -> deletes rating and note. Should be a single backend operation (cascade delete), not three separate calls from the client. Beware.

App.tsx now calls on the new page instead of the placeholder.
Update dependent imports to reflect this change.
Note: Checked that `npm run build` does not throw errors at this stage. Neat.
@ilsea ilsea requested a review from a team as a code owner October 8, 2026 19:57
@ilsea ilsea linked an issue Oct 8, 2026 that may be closed by this pull request
Copy link
Member

@ronnenga ronnenga left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ser nice ut, bra jobba

@ronnenga ronnenga merged commit 0ccd192 into main Oct 8, 2026
@ilsea ilsea deleted the 29-create-book-details-page branch October 8, 2026 20:10
Sign in to join this conversation on GitHub.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Create book details page Create components for frontend Create base pages and components
2 participants